public class singleNumbers {
    public int[] _singleNumbers(int[] nums) {
        int x = 0;// 用于记录 A B 的异或结果
        /**
         * 得到A^B的结果
         * 基于异或运算的以下几个性质
         * 1. 交换律
         * 2. 结合律
         * 3. 对于任何数x，都有x^x=0，x^0=x
         */
        for (int val : nums) {
            x ^= val;
        }
        // x & (-x)本身的作用是得到最低位的1
        int flag = x & (-x);
        // 而我们所需要的做到的是：利用这个1来进行分组，也就是做到将A和B区分开
        // 前面已经知道，x是我们需要的结果数A和B相异或的结果，也就是说，x的二进制串上的任何一个1，都能成为区分A和B的条件
        // 因此我们只需要得到x上的任意一个1，就可以做到将A和B区分开来
        int res = 0; // 用于记录A或B其中一者
        // 分组操作
        for (var val : nums) {
            if ((flag & val) != 0) {
                res ^= val;
            }
        }
        return new int[] { res, x ^ res };
    }
}
